using System.Collections.Generic;
using System.Linq;
using RimWorld;
using Verse;

namespace RimZombieGirl
{
    public class RI_ZombieLevelsDef : Def
    {
        public List<RI_ZombieLevelDef> levels;

        public RI_ZombieLevelDef GetLevelDef(int level, string branch)
        {
            return levels.FirstOrDefault(l => l.level == level && l.branch == branch);
        }

        public RI_ZombieLevelDef GetNextLevelDef(int level, string branch)
        {
            return levels.FirstOrDefault(l => l.level == level + 1 && l.branch == branch);
        }

        public RI_ZombieLevelDef GetFirstLevelDef()
        {
            return levels.FirstOrDefault(l => l.level == 1 && l.branch == "");
        }

        public RI_ZombieLevelDef GetNextRandomBranchLevelDef(int level)
        {
            var nextLevels = levels.Where(l => l.level == level + 1 && l.branch != "").ToList();
            if (nextLevels.Count == 0)
            {
                return null;
            }
            return nextLevels.RandomElement();
        }


        public override IEnumerable<string> ConfigErrors()
        {
            foreach (var error in base.ConfigErrors())
            {
                yield return error;
            }

            if (levels == null)
            {
                yield return "levels list is null";
                yield break;
            }

            // Check for exactly one level 1 and it must be in branch ""
            var level1Items = levels.Where(l => l.level == 1).ToList();
            if (level1Items.Count != 1)
            {
                yield return "There must be exactly one level 1 definition.";
            }
            else if (level1Items[0].branch != "")
            {
                yield return "Level 1 must have an empty branch.";
            }

            var branchGroups = levels.GroupBy(l => l.branch ?? "");

            foreach (var group in branchGroups)
            {
                var branch = group.Key;
                var levelSet = new HashSet<int>();

                foreach (var item in group)
                {
                    if (!levelSet.Add(item.level))
                    {
                        yield return $"Branch '{branch}' has duplicate level {item.level}";
                    }
                }

                if (levelSet.Count == 0)
                {
                    continue; // Skip if no levels for this branch
                }

                // Check if levels start from 1
                if (levelSet.Min() != 1)
                {
                    yield return $"Branch '{branch}' levels must start from 1";
                }

                // Check for consecutive levels
                int maxLevel = levelSet.Max();
                for (int i = 1; i <= maxLevel; i++)
                {
                    if (!levelSet.Contains(i))
                    {
                        yield return $"Branch '{branch}' is missing level {i}";
                    }
                }
            }
        }
    }
}